package com.googlecode.dgwt.client.dijit.base;

import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.HasAllFocusHandlers;
import com.google.gwt.event.dom.client.HasAllKeyHandlers;
import com.google.gwt.event.dom.client.HasAllMouseHandlers;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.dom.client.MouseWheelEvent;
import com.google.gwt.event.dom.client.MouseWheelHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Focusable;
import com.googlecode.dgwt.client.dijit.Dijit;
import com.googlecode.dgwt.client.dijit.Widget;
import com.googlecode.dgwt.client.dijit.base.manager.FocusManager;
import com.googlecode.dgwt.client.dijit.base.state.DisabledState;
import com.googlecode.dgwt.client.dijit.theme.CSS;

/**
 * @author wellsantos@wellsantos.com
 * @since 0.01
 */
public class FocusWidget extends Widget implements Focusable, 
                                                   HasClickHandlers,
                                                   HasAllKeyHandlers,
                                                   HasAllFocusHandlers, 
                                                   HasAllMouseHandlers {

    protected FocusWidget(boolean ready) {
        super(ready);
    }

    public FocusWidget(Element element) {
        super(element);
    }


    protected FocusManager getFocusManager(){
        return FocusManager.get();
    }
    
    @Override
    protected void initialize() {
        super.initialize();
        setElementForAttribute("accessKey", "focusableElement");
        setElementForAttribute("disabled", "focusableElement");
        setElementForAttribute("tabindex", "focusableElement");
    }
    
    @Override
    protected void onPostCreate() {
        getFocusManager().onPostCreate(this);
    }

    @Override
    public CSS getThemeCSS() {
        return Dijit.getTheme().dijitFocusWidget();
    }

    public Element getFocusableElement(){
        return getAttachedElement("focusableElement");
    }    

    protected void setFocusableElement(Element element){
        setAttachedElement("focusableElement", element);
    }
      
    @Override
    public int getTabIndex() {
        return getFocusManager().getTabIndex(this);
    }

    @Override
    public void setTabIndex(int index) {
        getFocusManager().setTabIndex(this, index);
    }

    public boolean isEnabled() {
        return getFocusManager().isEnabled(this);
    }

    @Override
    public void setAccessKey(char key) {
        getFocusManager().setAccessKey(this, key);
    }

    public void setEnabled(boolean enabled) {
        getFocusManager().setEnabled(this, !enabled);
        if (enabled){
            removeState(DisabledState.get());
        } else {
            addState(DisabledState.get());
        }
    }
   
    public final void setFocus() {
        setFocus(true);
    }
    
    @Override
    public void setFocus(boolean focused) {
        getFocusManager().setFocus(this, focused);
    }

    public HandlerRegistration addBlurHandler(BlurHandler handler) {
        return addDomHandler(handler, BlurEvent.getType());
    }

    public HandlerRegistration addClickHandler(ClickHandler handler) {
        return addDomHandler(handler, ClickEvent.getType());
    }

    public HandlerRegistration addFocusHandler(FocusHandler handler) {
        return addDomHandler(handler, FocusEvent.getType());
    }

    public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
        return addDomHandler(handler, KeyDownEvent.getType());
    }

    public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
        return addDomHandler(handler, KeyPressEvent.getType());
    }

    public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) {
        return addDomHandler(handler, KeyUpEvent.getType());
    }

    public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) {
        return addDomHandler(handler, MouseDownEvent.getType());
    }

    public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) {
        return addDomHandler(handler, MouseMoveEvent.getType());
    }

    public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
        return addDomHandler(handler, MouseOutEvent.getType());
    }

    public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
        return addDomHandler(handler, MouseOverEvent.getType());
    }

    public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
        return addDomHandler(handler, MouseUpEvent.getType());
    }

    public HandlerRegistration addMouseWheelHandler(MouseWheelHandler handler) {
        return addDomHandler(handler, MouseWheelEvent.getType());
    }

}
